package edu.ubb.remeye.client.settings;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.codecompany.jeha.ExceptionHandler;
import org.codecompany.jeha.core.HandlerUtil;

import edu.ubb.remeye.client.settings.jaxb.ClientSettings;
import edu.ubb.remeye.encodings.EncodingType;
import edu.ubb.remeye.exception.SettingsLoadingException;
import edu.ubb.remeye.exception.SettingsSavingException;
import edu.ubb.remeye.exception.handler.RemEyeExceptionHandler;
import edu.ubb.remeye.security.SecurityType;
import edu.ubb.remeye.util.jaxb.JAXBBinder;

/**
 * Settings class manager for client.
 * 
 * @author Andrew Ianicicau
 *
 */
@ExceptionHandler(handler=RemEyeExceptionHandler.class)
public class ClientSetter {

	///////////////////////////////////////////////////////////////////////////////////
	////		ATTRIBUTES - ClientSetter
	///////////////////////////////////////////////////////////////////////////////////

	/**
	 * Private attribute of this class for singleton design pattern.
	 */
	private static ClientSetter clientSetter;
	
	/**
	 * JAXB object, settings are stored in it.
	 */
	private static ClientSettings settings;

	
	
	///////////////////////////////////////////////////////////////////////////////////
	////		CONSTRUCTORS - ClientSetter
	///////////////////////////////////////////////////////////////////////////////////

	private ClientSetter() {
		try {
			settings = (ClientSettings) JAXBBinder.loadSettings(false);
		} catch (SettingsLoadingException e) {
			HandlerUtil.handle(e);
		}
		
		if(settings == null) {
			settings = new ClientSettings();
			settings.setIp("localhost");
			settings.setPort(5900);
			settings.setDesiredSecurity(SecurityType.VNC.ordinal());
			settings.setDesiredEncoding(EncodingType.JPEG.ordinal());
			settings.setControl(false);
			saveSettings();
		}
	}
	
	
	
	///////////////////////////////////////////////////////////////////////////////////
	////		METHODS - ClientSetter
	///////////////////////////////////////////////////////////////////////////////////
	
	/**
	 * Singleton design pattern instance provider method.
	 */
	public static ClientSetter getInstance() {
		if(clientSetter == null)
			clientSetter = new ClientSetter();
		return clientSetter;
	}
	
	public String getIp() {
		return settings.getIp();
	}
	
	public void setIp(String ip) {
		// pattern matching for IP
		Pattern pattern = Pattern.compile("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)");
		Matcher matcher = pattern.matcher(ip);
		if((matcher.find() && matcher.group().equals(ip)) || ip.equals("localhost")) {
			settings.setIp(ip);
		}
	}
	
	public int getPort() {
		return settings.getPort();
	}
	
	public void setPort(int port) {
		// port must be between 1024 and 65536 
		if(port > 1024 && port < 65536) {
			settings.setPort(port);
		}
	}
	
	public SecurityType getDesiredSecurityType() {
		int ordinal = settings.getDesiredSecurity();
		return SecurityType.getSecurityType(ordinal);
	}
	
	public void setDesiredSecurityType(SecurityType type) {
		settings.setDesiredSecurity(type.ordinal());
	}
	
	public EncodingType getDesiredEncodingType() {
		int ordinal = settings.getDesiredEncoding();
		return EncodingType.getEncodingType(ordinal);
	}
	
	public void setDesiredEncodingType(EncodingType type) {
		settings.setDesiredEncoding(type.ordinal());
	}
	
	public boolean getControl() {
		return settings.isControl();
	}
	
	public void setControl(boolean control) {
		settings.setControl(control);
	}
	
	public void saveSettings() {
		try {
			JAXBBinder.saveSettings(settings, false);
		} catch(SettingsSavingException e) {
			HandlerUtil.handle(e);
		};
	}
}
